package com.ryzx.log.collector;

import com.ryzx.common.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;



/*
servcie层日志处理，记录入参、出参
 */
@Slf4j
@Aspect
public class ServiceLogHandler extends AbstractLogHandler {
    private static final String SERVICE_MESSAGE_FORMAT = "handle class=[{0}],handle method=[{1}],Param=[{2}],Response=[{3}],cost time=[{4}ms-({5})]";
    private static final String SERVICE_MESSAGE_ERROR_FORMAT = "handle class=[{0}],handle method=[{1}],Param=[{2},stackTrac=[\n{3}]]";
    @Pointcut("@within(org.springframework.stereotype.Service) && execution(public * *(..))")
    public void servicePointcut() {

    }
    @Around("servicePointcut()")
    public Object doControllerAround(ProceedingJoinPoint point) throws Throwable {
        String traceId = RequestLogContext.getTraceId();
        if(traceId==null)
            traceId=super.processRequestTraceId();
        Long startTime = System.currentTimeMillis();
        String methodName = point.getSignature().getName();
        String className = point.getSignature().getDeclaringTypeName();
        Object[] params = point.getArgs();
        boolean outputLogMark = super.isOutPutLog(params);
        Object serviceResp = point.proceed();
        Long endTime = System.currentTimeMillis();
        long costTime = endTime - startTime;
        if (outputLogMark) {
            String paramsStr = JsonUtil.obj2String(params);
            String rspStr = JsonUtil.obj2String(serviceResp);
            String timeFlag = getTimeCostFlag(costTime);
            log.info("{\"traceId\":\"{}\",\"url\":\"{}\",\"method\":\"{}\",\"handleClass\":\"{}\",\"handleMethod\":\"{}\",\"param\":\"{}\",\"response\":{},\"costTime\":\"{}\",\"timeLevel\":\"{}\",\"stackTrace\":\"{}\"}",
                    traceId,"","",className,methodName,paramsStr,rspStr,costTime,timeFlag,"");
        }
        return serviceResp;
    }
    @AfterThrowing(pointcut = "servicePointcut()", throwing = "e")
    public void handle(JoinPoint point, Exception e) {
        String traceId = RequestLogContext.getTraceId();
        if(traceId==null)
            traceId=super.processRequestTraceId();
        String methodName = point.getSignature().getName();
        String className = point.getSignature().getDeclaringTypeName();
        Object[] params = point.getArgs();
        String paramsStr = JsonUtil.obj2String(params);
        String stackTrace=e.toString();
        log.error("{\"traceId\":\"{}\",\"url\":\"{}\",\"method\":\"{}\",\"handleClass\":\"{}\",\"handleMethod\":\"{}\",\"param\":\"{}\",\"response\":{},\"costTime\":\"{}\",\"timeLevel\":\"{}\",\"stackTrace\":\"{}\"}",
                traceId,"","",className,methodName,paramsStr,"\"\"",-1,"",stackTrace);

    }
}
